import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hack_a_tone/bloc/apps_keeper.dart';
import 'package:hack_a_tone/bloc/tracker.dart';

sealed class BackTimerState {
  const BackTimerState({required this.apps, this.currentApps});
  final List<String>? currentApps;
  final Timeline apps;
}

final class BackTimerRuning extends BackTimerState {
  const BackTimerRuning({required super.apps, super.currentApps});

  @override
  String toString() => 'BackTimerRuning { duration: $apps }';
}

final class BackTimerStopped extends BackTimerState {
  const BackTimerStopped({required super.apps, super.currentApps});

  @override
  String toString() => 'BackTimerStopped { duration: $apps }';
}

sealed class BackWindowKeeperEvent {}

final class _FetchBackWindows extends BackWindowKeeperEvent {
  _FetchBackWindows({required this.name});
  List<String> name;
}

final class StartTrackingBackWindows extends BackWindowKeeperEvent {}

final class StopTrackingBackWindows extends BackWindowKeeperEvent {}

class BackWindowKeeperBloc extends Bloc<BackWindowKeeperEvent, BackTimerState> {
  BackWindowKeeperBloc({required Ticker ticker})
      : _ticker = ticker,
        super(const BackTimerStopped(apps: {})) {
    on<StartTrackingBackWindows>(_onStarted);
    on<StopTrackingBackWindows>(_onPaused);
    on<_FetchBackWindows>(_onTicked);
  }

  final Ticker _ticker;

  StreamSubscription<List<String>>? _tickerSubscription;

  @override
  Future<void> close() {
    _tickerSubscription?.cancel();
    return super.close();
  }

  void _onStarted(StartTrackingBackWindows event, Emitter<BackTimerState> emit) {
    emit(BackTimerRuning(apps: state.apps));
    _tickerSubscription?.cancel();
    _tickerSubscription =
        _ticker.tickBack().listen((app) => add(_FetchBackWindows(name: app)));
  }

  void _onPaused(StopTrackingBackWindows event, Emitter<BackTimerState> emit) {
    if (state is TimerRuning) {
      _tickerSubscription?.cancel();
      emit(BackTimerStopped(apps: state.apps));
    }
  }

  void _onTicked(_FetchBackWindows event, Emitter<BackTimerState> emit) {
    Timeline st = {};
    st.addAll(state.apps);
    List<String>? currentApps = state.currentApps;
    if (currentApps != null) {
      for (var app in event.name) {
        if (st.containsKey(app)) {
          if (currentApps.contains(app)) {
            var lastDelay = st[app]!.last;
            st[app]!.last = DateTimeRange(
                start: lastDelay.start,
                end: lastDelay.end.add(const Duration(seconds: 1)));
          } else {
            st[app]!
                .add(DateTimeRange(start: DateTime.now(), end: DateTime.now()));
          }
        } else {
          List<DateTimeRange> a = [];
          a.add(DateTimeRange(start: DateTime.now(), end: DateTime.now()));
          st[app] = a;
              
        }
      }
    }
    emit(BackTimerRuning(apps: st, currentApps: event.name));
  }
}
